package org.agony2d.gpu.core {
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.VertexBuffer3D;
	import flash.geom.Matrix3D;
	
	import org.agony2d.core.agony_internal;
	import org.agony2d.debug.Logger;
	import org.agony2d.gpu.AgonyAA;
	import org.agony2d.gpu.FusionAA;
	import org.agony2d.gpu.supportClasses.programs.ProgramProxy;
	import org.agony2d.gpu.supportClasses.textures.FullTexture;
	import org.agony2d.notify.AEvent;
	
	use namespace agony_internal;
	
public class GroupAA extends FusionAA {
	
	public function GroupAA() {
		AgonyAA.addEventListener(AEvent.RESET, ____onResetBuffers)
	}
	
	agony_internal function setting( fullTextureName:String, tinted:Boolean, smoothing:Boolean ) : void {
		m_fullTexture = g_textureList[fullTextureName]
		if (!m_fullTexture) {
			Logger.reportError(this, "constructor", "full texture (" + fullTextureName + ") can't be null...!!")
		}
		m_tinted = tinted
		m_smoothing = smoothing
		m_program = ProgramProxy.retrieve(tinted, smoothing, m_fullTexture.m_mipmapEnabled)
	}
	
	override agony_internal function dispose() : void {
		AgonyAA.removeEventListener(AEvent.RESET, ____onResetBuffers)
		if (m_vb3d) {
			m_vb3d.dispose()
			m_ib3d.dispose()
		}
		super.dispose()
	}
	
	override agony_internal function render( vertexChanged:Boolean, tinted:Boolean ) : void {
		if (!m_program || m_numNodes <= 0 || m_invisible) {
			return
		}
		this.doFinishPrevGroup()
		this.doIntegrateVertex(vertexChanged, tinted)
		goFinishRender()
		this.doResumePrevGroup()
	}
	
	agony_internal function doFinishPrevGroup() : void {
		if (g_currGroup) {
			m_prevGroup        =  g_currGroup
			m_prevFullTexture  =  g_currFullTexture
			m_prevProgram      =  g_currProgram
			goFinishRender()
		}
	}
	
	agony_internal function doIntegrateVertex( vertexChanged:Boolean, tinted:Boolean ) : void {
		g_currGroup        =  this
		g_currFullTexture  =  m_fullTexture
		g_currProgram      =  m_program
		this.doExtractNodes(vertexChanged, m_tinted)
	}
	
	agony_internal static function goFinishRender() : void {
		g_convergence.updateTotalAndIndexList()
		if (g_convergence.m_totalNodes > 0) {
			g_currProgram.uploadAllBuffers(g_currGroup)
			g_currProgram.setProperties(g_currFullTexture)
			g_currProgram.drawAndReset()
			//g_drawCount++
		}
	}
	
	agony_internal function doResumePrevGroup() : void {
		if (m_prevGroup) {
			g_currGroup        =  m_prevGroup
			g_currFullTexture  =  m_prevFullTexture
			g_currProgram      =  m_prevProgram
			m_prevGroup        =  null
		}
		else {
			g_currGroup = null
		}
	}
	
	agony_internal function set totalNodes( v:int ) : void {
		if (m_totalNodes != v) {
			m_totalNodes = v
			this.doUpdateVertexAndIndexBuffer(v)
		}
	}
	
	
	agony_internal static var g_currGroup:GroupAA
	
	agony_internal var m_prevGroup:GroupAA
	agony_internal var m_program:ProgramProxy, m_prevProgram:ProgramProxy
	agony_internal var m_tinted:Boolean, m_smoothing:Boolean
	agony_internal var m_prevFullTexture:FullTexture
	agony_internal var m_vb3d:VertexBuffer3D
	agony_internal var m_ib3d:IndexBuffer3D
	agony_internal var m_totalNodes:int
	
	
	
	agony_internal function ____onResetBuffers( e:AEvent ) : void {
		if(m_totalNodes > 0){
			this.doUpdateVertexAndIndexBuffer(m_totalNodes)
		}
	}
	
	agony_internal function doUpdateVertexAndIndexBuffer( numNodes:int ) : void {
		if (m_vb3d) {
			m_vb3d.dispose()
			m_ib3d.dispose()
		}
		m_vb3d = g_context3d.createVertexBuffer(numNodes * 4, 5)
		m_ib3d = g_context3d.createIndexBuffer(numNodes * 6)
	}
}
}